package com.nineclock.system.service.impl;

import cn.hutool.core.util.RandomUtil;
import com.nineclock.common.constant.SMSConstant;
import com.nineclock.common.enums.ResponseEnum;
import com.nineclock.common.exception.NcException;
import com.nineclock.common.sms.SmsUtils;
import com.nineclock.common.utils.PhoneNumCheckUtils;
import com.nineclock.common.utils.ValidateCodeUtils;
import com.nineclock.system.service.SysSmsService;
import com.nineclock.system.service.SysUserService;
import io.jsonwebtoken.lang.Collections;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.Map;
import java.util.concurrent.TimeUnit;

@Service
@Slf4j
public class SysSmsServiceImpl implements SysSmsService {

    @Autowired
    private SmsUtils smsUtils;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    /**
     * 发送验证码
     *
     * @return
     */
    @Autowired
    private SysUserService sysUserService;

    @Override
    public void sms(Map<String, String> map) {

        //参数校验
        if (Collections.isEmpty(map)) {
            throw new NcException(ResponseEnum.INVALID_PARAM_ERROR);
        }
        String mobileNum = map.get("mobile");
        String type = map.get("type");

        //判断手机号格式是否正确
        if (!PhoneNumCheckUtils.isPhoneLegal(mobileNum)) {
            throw new NcException(ResponseEnum.INVALID_PHONE_NUMBER);
        }
        //判断业务类型

        if (type.equals(SMSConstant.SMS_TYPE_REGISTER)) {
            //如果是注册业务,那么手机号在表中不能存在
            Boolean flag = sysUserService.checkMobileExists(mobileNum);
            if (flag) {
                throw new NcException(ResponseEnum.USER_MOBILE_EMAIL_EXISTS);
            }
        } else {
            //不是注册业务 手机号在表中一定要存在
            Boolean flag = sysUserService.checkMobileExists(mobileNum);
            if (!flag) {
                throw new NcException(ResponseEnum.USER_NOT_REGISTER);
            }
        }

        //生成验证码 6位纯数字
        //String validateCode = String.valueOf(ValidateCodeUtils.generateValidateCode(6));
        String validateCode = RandomUtil.randomNumbers(6);

        //发送验证码短信
//        boolean result = smsUtils.sendSms(mobileNum, validateCode);
//
//        //结果判断
//        if (!result) {
//            throw new NcException(ResponseEnum.SEND_MESSAGE_ERROR);
//        }

        //验证码发送成功后保存验证码到redis中
        //redis的key为 "type : mobilPhone"
        String redisKey = getPrefix(type) + mobileNum;
        stringRedisTemplate.opsForValue().set(redisKey, validateCode, 5, TimeUnit.MINUTES);

        // log.info("key为: " + redisKey + ",值为:" + stringRedisTemplate.opsForValue().get(redisKey));
        log.info("成功发送验证码 , {}->{} ", mobileNum, validateCode);
    }

    /**
     * 根据类型获取redis的key名称
     */
    private String getPrefix(String type) {
        switch (type) {
            case SMSConstant.SMS_TYPE_LOGIN:
                return SMSConstant.SMS_LOGIN_KEY_PREFIX;
            case SMSConstant.SMS_TYPE_REGISTER:
                return SMSConstant.SMS_REGISTER_KEY_PREFIX;
            case SMSConstant.SMS_TYPE_CHANGE_MANAGER:
                return SMSConstant.SMS_CHANGE_MANAGER_KEY_PREFIX;
            case SMSConstant.SMS_TYPE_RESET_PASSWORD:
                return SMSConstant.SMS_RESET_KEY_PREFIX;
            default:
                return null;
        }
    }


    /**
     * 验证码校验
     *
     * @return
     */
    @Override
    public Boolean verify(Map<String, String> map) {

        //参数校验
        if (Collections.isEmpty(map)) {
            throw new NcException(ResponseEnum.INVALID_PARAM_ERROR);
        }

        String mobileNum = map.get("mobile");
        String type = map.get("type");
        String checkcode = map.get("checkcode");

        //获取rediskey
        String redisKey = getPrefix(type) + mobileNum;


        //判断验证码是否存在 比较验证码
        String validateCode = stringRedisTemplate.opsForValue().get(redisKey);
        if (!StringUtils.isEmpty(validateCode) && validateCode.equals(checkcode)) {
            //验证成功后将redis中的验证码删除
            stringRedisTemplate.delete(redisKey);
            return true;
        }
        //否则失败
        return false;
    }
}
